package com.platform.modules.app.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.platform.annotation.LoginUser;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.*;
import com.platform.modules.mall.entity.*;
import com.platform.modules.mall.entity.dto.CardAssignDto;
import com.platform.modules.mall.service.*;
import com.platform.modules.sys.service.SysConfigService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@SuppressWarnings("DuplicatedCode")
@Slf4j
@RestController
@RequestMapping("/app/whitelist")
@Api(tags = "AppWhitelistController|白名单数据")
public class AppWhitelistController {

    @Autowired
    MallWhitelistService whitelistService;
    @Autowired
    MallCardSnService cardSnService;
    @Autowired
    SysConfigService sysConfigService;
    @Autowired
    private MallUserCardService mallUserCardService;
    @Autowired
    private MallReceiveLogService receiveLogService;
    @Autowired
    private MallActivityService activityService;
    @Autowired
    private MallGoodsToActivityService goodsToActivityService;
    @Autowired
    private MallGoodsService goodsService;
    @Autowired
    private MallOrderService orderService;

    /**
     * 获取用户可以抽奖次数
     *
     * @return RestResponse
     */
    @GetMapping("getInfo")
    @ApiOperation(value = "获取用户白名单信息", notes = "获取用户白名单信息")
    public RestResponse getInfo(@LoginUser MallUserEntity userEntity, @RequestParam String activityId) {
        ValidUtils.allNotNull(activityId);
        if (StringUtils.isBlank(userEntity.getMobile())) {
            return RestResponse.error("请绑定手机号");
        }
        ActivityStatusResult statusResult = activityService.getActivityStatus(activityId, null);
        if (!statusResult.getIsStart()) {
            return RestResponse.error("活动未开始");
        }
        //白名单是否加密
        String isMd5= sysConfigService.getValue("WHITELIST_MD5");
        MallWhitelistEntity entity = whitelistService.lambdaQuery()
                .select(MallWhitelistEntity::getNumber, MallWhitelistEntity::getLevel)
                .eq(MallWhitelistEntity::getPhone, Constant.STR_ONE.equals(isMd5)? Md5Utils.encrypt(userEntity.getMobile()):userEntity.getMobile())
                .eq(MallWhitelistEntity::getType, statusResult.getWhitelistType())
                .eq(MallWhitelistEntity::getValid, 1)
                .orderByAsc(MallWhitelistEntity::getLapseTime)
                .last(" LIMIT 1")
                .one();
        if (entity == null) {
            return RestResponse.error("非常抱歉，您暂不符合活动资格");
        }
        return RestResponse.success()
                .put("num", entity.getNumber())
                .put("level", entity.getLevel());
    }

    @PostMapping("selectCard")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", name = "params", value = "JSON格式参数", examples = @Example({
                    @ExampleProperty(mediaType = "mobile", value = "用户手机号"),
                    @ExampleProperty(mediaType = "goodsId", value = "商品id"),
                    @ExampleProperty(mediaType = "type", value = "白名单类型"),
            }), required = true, dataType = "string")
    })
    @ApiOperation(value = "白名单用户领取", notes = "白名单用户领取")
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public RestResponse selectCard(@LoginUser MallUserEntity loginUser, @RequestBody JSONObject jsonObject) {
        String goodsId = jsonObject.getString("goodsId");
        String mobile = jsonObject.getString("mobile");
        Integer type = jsonObject.getInteger("type");

        activityChecking(type);
        MallReceiveLogEntity platformReceiveLogEntity;
        MallGoodsEntity goodsEntity = null;
        MallWhitelistEntity whitelistEntity;
        String isMd5= sysConfigService.getValue("WHITELIST_MD5");
        whitelistEntity = whitelistService.getOne(new LambdaQueryWrapper<MallWhitelistEntity>()
                .eq(MallWhitelistEntity::getValid, Constant.ONE)
                .eq(MallWhitelistEntity::getPhone,Constant.STR_ONE.equals(isMd5)? Md5Utils.encrypt(mobile):mobile)
                .eq(MallWhitelistEntity::getType, type)
                .orderByAsc(MallWhitelistEntity::getLapseTime)
                .last(" LIMIT 1"));
        if (whitelistEntity == null) {
            return RestResponse.error("非常抱歉，您暂不符合购买资格！");
        }
        platformReceiveLogEntity = receiveLogService.getOne(new LambdaQueryWrapper<MallReceiveLogEntity>()
                .eq(MallReceiveLogEntity::getType, type).eq(MallReceiveLogEntity::getMobile, Md5Utils.encrypt(mobile)));
        if (platformReceiveLogEntity != null && StringUtils.isNotBlank(platformReceiveLogEntity.getId())) {
            return RestResponse.error("每人只能领取一次").put("code", 205);
        }
        whitelistEntity.setValid(Constant.ZERO);
        whitelistService.updateById(whitelistEntity);
        CardAssignDto dto = new CardAssignDto();
        dto.setGoodsId(goodsId);
        List<String> userIds = new ArrayList<>(1);
        userIds.add(loginUser.getId());
        // 用户活动领取
        dto.setPayType(7);
        dto.setUserId(userIds);
        dto.setCartNo(Long.valueOf(mobile));
        if (mallUserCardService.cardAssingn(dto)) {
            MallReceiveLogEntity receiveLogEntity = new MallReceiveLogEntity();
            receiveLogEntity.setAddTime(new Date());
            receiveLogEntity.setCardId(goodsId);
            receiveLogEntity.setCardName(goodsEntity == null ? null : goodsEntity.getName());
            receiveLogEntity.setMobile(mobile);
            receiveLogEntity.setNickname(loginUser.getNickname());
            receiveLogEntity.setType(type);
            receiveLogEntity.setUserId(loginUser.getId());
            receiveLogService.add(receiveLogEntity);
        }
        return RestResponse.success("发放成功").put("cardName", goodsEntity == null ? "" : goodsEntity.getName());
    }


    @GetMapping("getCardList")
    @ApiOperation(value = "获取商品信息", notes = "获取商品信息")
    @ApiImplicitParam(paramType = "body", name = "params", value = "JSON格式参数", examples = @Example({
            @ExampleProperty(mediaType = "type", value = "1激活有礼，2达标有礼")
    }), required = true, dataType = "string")
    @ApiResponses({
            @ApiResponse(code = 200, message = "OK", response = MallActivityEntity.class),
            @ApiResponse(code = 0, message = "OK", response = MallGoodsEntity.class),
    })
    public RestResponse selectCard(@LoginUser MallUserEntity user, Integer type) {
        MallActivityEntity mallActivityEntity = activityChecking(type);
        List<String> list = goodsToActivityService.list(new LambdaQueryWrapper<MallGoodsToActivityEntity>().select(MallGoodsToActivityEntity::getGoodsId)
                .eq(MallGoodsToActivityEntity::getActivityId, mallActivityEntity.getId()))
                .stream().map(i -> i.getGoodsId()).collect(Collectors.toList());
        List<MallGoodsEntity> goodsEntities = new ArrayList<>();
        if( CollectionUtils.isNotEmpty(list)){
           goodsEntities = goodsService.list(new LambdaQueryWrapper<MallGoodsEntity>().eq(MallGoodsEntity::getIsOnSale,1)
                    .in(MallGoodsEntity::getId, list));
        }
        goodsService.setGoodsRedisCount(mallActivityEntity.getId());
        Map<String, Object> map = this.getShoppingCount(user.getMobile(), mallActivityEntity.getId());
        return RestResponse.success().put("data", mallActivityEntity).put("list", goodsEntities).put("shoppingCount", map.get("shoppingCount")).put("isPayOrder", map.get("isPayOrder"));
    }

    @GetMapping("/queryUserQualification")
    @ApiOperation(value = "查询白名单资格", notes = "查询白名单资格")
    public RestResponse queryUserQualification(String mobile, Integer type) {
        String isMd5= sysConfigService.getValue("WHITELIST_MD5");
        MallActivityEntity activityEntity = this.activityChecking(type);
        MallWhitelistEntity whitelistEntity = whitelistService.lambdaQuery()
                .eq(MallWhitelistEntity::getPhone, Md5Utils.encrypt(mobile))
                .eq(MallWhitelistEntity::getType, type)
                .eq(MallWhitelistEntity::getValid, Constant.ONE)
                .orderByAsc(MallWhitelistEntity::getLapseTime)
                .last(" LIMIT 1").one();
        if (ObjectUtils.allNotNull(whitelistEntity)) {
            Map<String, Object> map = this.getShoppingCount(mobile, activityEntity.getId());
            return RestResponse.success().put("shoppingCount", map.get("shoppingCount")).put("isPayOrder", map.get("isPayOrder"));
        }
        return RestResponse.error("暂无资格");
    }

    MallActivityEntity activityChecking(Integer type) {
        MallActivityEntity activity = activityService.getOne(new LambdaQueryWrapper<MallActivityEntity>()
                .eq(MallActivityEntity::getWhitelistType, type));
        if (activity == null) {
            throw new BusinessException("该活动已结束，敬请期待");
        }
        LocalDate[][] dates = JSONObject.parseObject(activity.getActivityDate(), LocalDate[][].class);
        final LocalDate now = LocalDate.now();
        LocalDate[] date = null;
        int index = 0;
        for (int i = 0; i < dates.length; i++) {
            LocalDate[] item = dates[i];
            if (now.compareTo(item[0]) >= 0 && now.compareTo(item[1]) <= 0) {
                // 符合条件
                date = item;
                break;
            }
        }
        java.time.LocalTime[][] times = JSONObject.parseObject(activity.getActivityTime(), java.time.LocalTime[][].class);
        LocalTime nowTime = LocalTime.now();
        LocalTime[] time = null;
        for (int i = 0; i < times.length; i++) {
            java.time.LocalTime[] item = times[i];
            if (nowTime.compareTo(item[0]) >= 0 && nowTime.compareTo(item[1]) <= 0) {
                time = item;
                break;
            }
        }
        if (date == null) {
            date = dates[index];
            // activitFlag  -1 已经结束   1 进行中  2 未开始
            if (now.compareTo(date[1]) > 0) {
                activity.setBuyStatus(2);
            } else {
                activity.setBuyStatus(-1);
            }
        } else {
            if (time == null) {
                time = times[index];
                if (nowTime.compareTo(time[1]) > 0) {
                    activity.setBuyStatus(-1);
                } else {
                    activity.setBuyStatus(0);
                }
            } else {
                activity.setBuyStatus(1);
            }
        }
        return activity;
    }


    public Map<String, Object> getShoppingCount(String mobile, String activityId) {
        List<MallOrderEntity> orderList = orderService.lambdaQuery().eq(MallOrderEntity::getActivityId, activityId)
                .eq(MallOrderEntity::getPayStatus, Constant.PayStatus.YFK.getValue()).eq(MallOrderEntity::getMobile, Md5Utils.encrypt(mobile))
                .last("AND DATE_FORMAT(add_time,\"%Y-%m\") = DATE_FORMAT(now(),\"%Y-%m\")")
                .list();
        List<MallOrderEntity> orderList1 = orderService.lambdaQuery().eq(MallOrderEntity::getActivityId, activityId)
                .eq(MallOrderEntity::getOrderStatus, Constant.OrderStatus.DFK).eq(MallOrderEntity::getMobile, Md5Utils.encrypt(mobile))
                .last("AND DATE_FORMAT(add_time,\"%Y-%m\") = DATE_FORMAT(now(),\"%Y-%m\")")
                .list();
        Integer shoppingCount = 2 - orderList.size() - orderList1.size();
        Integer isPayOrder = 0;
        if (CollectionUtils.isNotEmpty(orderList1)) {
            isPayOrder = 1;
        }
        if (shoppingCount <= 0) {
            isPayOrder = 2;
        }
        if (shoppingCount == 2) {
            isPayOrder = 0;
        }
        Map<String, Object> map = new HashMap<>();
        map.put("shoppingCount", shoppingCount);
        map.put("isPayOrder", isPayOrder);
        return map;
    }
}